package com.googlewell.zelix;

import com.googlewell.zelix.analy.ZelixAnaly;
import com.googlewell.zelix.test.WriteClass;
import com.googlewell.zelix.ui.TextInput;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import me.coley.recaf.config.Conf;
import me.coley.recaf.config.FieldWrapper;
import me.coley.recaf.control.Controller;
import me.coley.recaf.control.gui.GuiController;
import me.coley.recaf.plugin.api.ConfigurablePlugin;
import me.coley.recaf.plugin.api.ContextMenuInjectorPlugin;
import me.coley.recaf.plugin.api.MenuProviderPlugin;
import me.coley.recaf.plugin.api.StartupPlugin;
import me.coley.recaf.ui.ContextBuilder;
import me.coley.recaf.ui.controls.ActionButton;
import me.coley.recaf.ui.controls.ActionMenuItem;
import me.coley.recaf.ui.controls.NumberSlider;
import me.coley.recaf.util.LangUtil;
import me.coley.recaf.workspace.JavaResource;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.plugface.core.annotations.Plugin;

import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;

@Plugin(name = "zelix")
public class ZelixPlugin implements StartupPlugin, ConfigurablePlugin, ContextMenuInjectorPlugin, MenuProviderPlugin {

    private Controller controller;

    //key,语言json文件定义实际内容。addFieldEditors()方法也会用到,所以定义为变量,没有直接写入注解
    private static final String NUMBERSLIDER = "zelix.config.slide";
    //value,noTranslate默认false,需要加载自己的语言json文件,如果没有需要设置为false
    @Conf(value = NUMBERSLIDER)
    public long minimumThreads = 15;

    private static final String TEXT = "zelix.config.text";
    @Conf(value = TEXT)
    public String ttt = "ceshi";

    //BasePlugin
    //插件管理里使用,不要使用translate
    @Override
    public String getVersion() {
        return "1.0";
    }

    //BasePlugin
    //插件管理里使用,不要使用translate
    @Override
    public String getDescription() {
        return "zelix分析插件";
    }

    //StartupPlugin
    @Override
    public void onStart(Controller controller) {
        this.controller = controller;

        //获取当前包中的资源
        URL url = ZelixPlugin.class.getClassLoader().getResource("translations/zelix.json");
        //加载语言文件,onStart()中加载有效,ConfigurablePlugin的load()无效
        LangUtil.load(url);
    }

    //ConfigurablePlugin
    @Override
    public String getConfigTabTitle() {
        return LangUtil.translate("zelix.config.title");
    }

    //ConfigurablePlugin
    @Override
    public void addFieldEditors(Map<String, Function<FieldWrapper, Node>> editors) {
        editors.put(NUMBERSLIDER, field -> new NumberSlider<Integer>((GuiController) controller, field, 1, 30, 1));
        editors.put(TEXT, field -> new TextInput(ttt, field));
    }

    //ContextMenuInjectorPlugin
    //在资源根路径添加右键菜单
    @Override
    public void forResourceRoot(ContextBuilder builder, ContextMenu menu, JavaResource resource) {
        menu.getItems().add(new ActionMenuItem(LangUtil.translate("zelix.root.menu.title"), () -> ZelixAnaly.analy(controller, resource)));
    }

    //ContextMenuInjectorPlugin
    //属性右键菜单,属性面板和汇编窗口都可用
    @Override
    public void forField(ContextBuilder builder, ContextMenu menu, String owner, String name, String desc) {
        menu.getItems().add(new ActionMenuItem("测试属性", () -> System.out.println("Field右键测试")));
    }

    //ContextMenuInjectorPlugin
    //搜索功能,打开折叠位置到指令级别可用
    @Override
    public void forInsn(ContextBuilder builder, ContextMenu menu, String owner, String name, String desc, AbstractInsnNode insn) {
        menu.getItems().add(new ActionMenuItem("测试指令", () -> System.out.println("Insn右键测试")));
    }

    //ContextMenuInjectorPlugin
    //方法右键菜单,方法面板和汇编窗口都可用
    @Override
    public void forMethod(ContextBuilder builder, ContextMenu menu, String owner, String name, String desc) {
        menu.getItems().add(new ActionMenuItem("测试方法", () -> System.out.println("Method右键测试")));
    }

    //ContextMenuInjectorPlugin
    //在资源路径class右键菜单
    @Override
    public void forClass(ContextBuilder builder, ContextMenu menu, String name) {
        menu.getItems().add(new ActionMenuItem("测试class", () -> WriteClass.test(controller, name)));
    }

    //MenuProviderPlugin
    //插件菜单创建子菜单
    @Override
    public Menu createMenu() {
        Menu menu = new Menu(getName());
        menu.getItems().addAll(new MenuItem[]{new ActionMenuItem("调试", () -> {

            GuiController gController = (GuiController) this.controller;
            Stage window = gController.windows().window(getName(), createReplacePanel());
            window.show();
        })});

        return menu;
    }

    private Parent createReplacePanel() {
        TextField txtInput = new TextField();
        GridPane grid = new GridPane();
        grid.addRow(0, new Node[]{new Label("需要调试的类:"), txtInput});
        grid.addRow(1, new Node[]{new ActionButton("开始调试", () -> {
            WriteClass.test1(this.controller,txtInput.getText());
            //隐藏移除创建的窗口
            GuiController gController = (GuiController) this.controller;
            Set<Stage> windows = gController.windows().getWindows();
            Iterator<Stage> iterator = windows.iterator();
            while (iterator.hasNext()){
                Stage win=iterator.next();
                win.close();
                windows.remove(win);
            }
        })});
        return grid;
    }
}